package cn.skillith.showcompanybackend.service;

import cn.skillith.showcompanybackend.entity.ContactMessage;
import cn.skillith.showcompanybackend.entity.DeviceLimit;
import cn.skillith.showcompanybackend.mapper.ContactMessageMapper;
import cn.skillith.showcompanybackend.mapper.DeviceLimitMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.MessageDigest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
public class ContactService {
    
    @Autowired
    private ContactMessageMapper contactMessageMapper;
    
    @Autowired
    private DeviceLimitMapper deviceLimitMapper;
    
    private static final int DAILY_LIMIT = 5;
    
    public String generateDeviceFingerprint(String ipAddress, String userAgent, 
                                          String acceptLanguage, String acceptEncoding) {
        try {
            String input = ipAddress + userAgent + acceptLanguage + acceptEncoding;
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException("生成设备指纹失败", e);
        }
    }
    
    public boolean checkDeviceLimit(String deviceFingerprint) {
        Optional<DeviceLimit> deviceLimitOpt = deviceLimitMapper.findByDeviceFingerprint(deviceFingerprint);
        LocalDate today = LocalDate.now();
        
        if (deviceLimitOpt.isEmpty()) {
            // 新设备，创建记录
            DeviceLimit deviceLimit = new DeviceLimit(deviceFingerprint);
            deviceLimitMapper.save(deviceLimit);
            return true;
        }
        
        DeviceLimit deviceLimit = deviceLimitOpt.get();
        
        // 检查是否被永久封禁
        if (deviceLimit.getIsBlocked() && deviceLimit.getBlockedUntil() != null 
            && LocalDateTime.now().isBefore(deviceLimit.getBlockedUntil())) {
            return false;
        }
        
        // 检查是否被临时封禁但已过期
        if (deviceLimit.getIsBlocked() && deviceLimit.getBlockedUntil() != null 
            && LocalDateTime.now().isAfter(deviceLimit.getBlockedUntil())) {
            // 解封
            deviceLimitMapper.updateBlockStatus(deviceFingerprint, false, null);
        }
        
        // 检查日期重置
        if (!deviceLimit.getLastResetDate().equals(today)) {
            deviceLimitMapper.updateDailyCount(deviceFingerprint, 0, today);
            return true;
        }
        
        // 检查每日限制
        return deviceLimit.getDailyCount() < DAILY_LIMIT;
    }
    
    @Transactional
    public boolean submitMessage(ContactMessage contactMessage) {
        String deviceFingerprint = contactMessage.getDeviceFingerprint();
        
        // 检查设备限制
        if (!checkDeviceLimit(deviceFingerprint)) {
            return false;
        }
        
        // 保存消息
        contactMessage.setCreatedAt(LocalDateTime.now());
        contactMessageMapper.save(contactMessage);
        
        // 更新设备计数
        deviceLimitMapper.incrementCount(deviceFingerprint);
        
        return true;
    }
    
    public Page<ContactMessage> getMessages(int page, int size, String status) {
        Pageable pageable = PageRequest.of(page, size);
        if ("all".equals(status)) {
            return contactMessageMapper.findAllOrderByCreatedAtDesc(pageable);
        } else {
            return contactMessageMapper.findByStatus(status, pageable);
        }
    }
    
    public long getMessageCount(String status) {
        if ("all".equals(status)) {
            return contactMessageMapper.count();
        } else {
            return contactMessageMapper.countByStatus(status);
        }
    }
    
    public void updateMessageStatus(Long id, String status, String adminNotes) {
        Optional<ContactMessage> messageOpt = contactMessageMapper.findById(id);
        if (messageOpt.isPresent()) {
            ContactMessage message = messageOpt.get();
            message.setStatus(ContactMessage.MessageStatus.valueOf(status));
            message.setAdminNotes(adminNotes);
            contactMessageMapper.save(message);
        }
    }
    
    public void blockDevice(String deviceFingerprint, int hours) {
        LocalDateTime blockedUntil = LocalDateTime.now().plusHours(hours);
        deviceLimitMapper.updateBlockStatus(deviceFingerprint, true, blockedUntil.toString());
    }
    
    public List<ContactMessage> getMessagesByDevice(String deviceFingerprint) {
        return contactMessageMapper.findByDeviceFingerprint(deviceFingerprint);
    }
    
    public ContactMessage getMessageById(Long id) {
        return contactMessageMapper.findById(id).orElse(null);
    }
}
